<?php

namespace app\common\service\organization;

use app\common\enums\core\AuditStateEnum;
use app\common\enums\core\UserTypeEnum;
use app\common\enums\LevelTypeEnum;
use app\common\enums\OrganizationStateEnum;
use app\common\enums\QuotaBusinessTypeEnum;
use app\common\model\banxi\organization\Organization;
use app\common\model\banxi\organization\OrganizationData;
use app\common\model\banxi\organization\OrganizationLevelConfig;
use app\common\model\banxi\organization\OrganizationOpenApply;
use app\common\model\banxi\organization\OrganizationQuotaRw;
use app\common\model\banxi\organization\OrganizationUser;
use app\common\service\ApiService;
use app\common\service\SnowflakeService;
use ba\Exception;
use think\db\exception\PDOException;
use think\exception\ValidateException;
use think\facade\Db;

class OrganizationService extends ApiService
{
    public function openApply(string $applyUserId, string $applyUserType, array $data, string $applyOrganizationId = '0')
    {
        Db::startTrans();
        try {
            $openApplyId = $data['openApplyId'] ?? 0;
            $openApply = new OrganizationOpenApply();
            $organization = $data;
            $organizationModel = new Organization();
            //判断是否有申请权限
            if ($applyOrganizationId != 0) {
                $applyOrganization = $organizationModel->where(['id' => $applyOrganizationId])->find();
                if (!$applyOrganization) {
                    throw new ValidateException('申请机构不存在');
                }
                $applyOrganizationLevel = $applyOrganization['level'];
                $applyOrganizationLevelInfo = OrganizationLevelConfig::where(['id' => $applyOrganizationLevel])->find();
                if (empty($applyOrganizationLevelInfo)) {
                    throw new ValidateException('申请机构等级不存在');
                }
                if ($applyOrganizationLevelInfo['levelType'] != LevelTypeEnum::E1) {
                    throw new ValidateException('你没有申请权限');
                }
            }
            $openPhone = $organization['openPhone'];
            $phoneExistsWhere = [
                ['openPhone', '=', $openPhone]
            ];
            if ($openApplyId) {
                $openApply = $openApply->where(['id' => $openApplyId])->find();
                if (!$openApply) {
                    throw new ValidateException('申请记录不存在');
                }
                if ($applyOrganizationId == $openApply['organizationId']) {
                    throw new ValidateException('无权限操作该数据');
                }
                if ($openApply['applyState'] == AuditStateEnum::E2) {
                    throw new ValidateException('申请已审核通过，不可修改');
                }
                $organizationId = $openApply['organizationId'];
                $phoneExistsWhere[] = ['id', '<>', $openApplyId];
            } else {
                $code = createRandomString('XF-', 8);
                $snowflakeService = new SnowflakeService(1, 1);
                $organizationId = $snowflakeService->nextId();
                $organization['code'] = $code;
                $organization['status'] = OrganizationStateEnum::E1;
                $parentId = $data['parentId'] ?: $applyOrganizationId;
                if ($parentId == 0) {
                    $organization['parentId'] = $parentId;
                    $organization['levelNum'] = 1;
                    $organization['parentPath'] = '0';
                } else {
                    $parentOrganization = $organizationModel->where(['id' => $parentId])->find();
                    if (!$parentOrganization) {
                        throw new ValidateException('所属机构不存在');
                    }
                    $organization['parentId'] = $parentId;
                    $organization['levelNum'] = $parentOrganization['levelNum'] + 1;
                    $organization['parentPath'] = $parentOrganization['parentPath'] . ',' . $parentOrganization['id'];
                }
            }
            $phoneExists = $organizationModel->where($phoneExistsWhere)->count();
            if ($phoneExists){
                throw new ValidateException('开户人手机号已存在');
            }
            $organization['id'] = $organizationId;
            $areas = $data['areas'];
            $organization['area'] = implode(',', $areas);
            $organizationModel->save($organization);
            $openApplyData = [
                'organizationId' => $organizationId,
                'organizationName' => $organization['name'],
                'organizationManager' => $organization['openName'],
                'organizationManagerPhone' => $organization['openPhone'],
                'applyState' => AuditStateEnum::E1,
                'applyOrganizationId' => $applyOrganizationId,
                'applyUserType' => $applyUserType
            ];
            switch ($applyUserType) {
                case UserTypeEnum::SYS_USER:
                    $openApplyData['applyUserId'] = $applyUserId;
                    break;
                case UserTypeEnum::ORGANIZATION:
                    $openApplyData['applyOrganizationId'] = $applyUserId;
                    break;
            }
            $openApply->save($openApplyData);
            if ($applyUserType == UserTypeEnum::SYS_USER) {
                $audit = [
                    'openApplyId' => $openApply['id'],
                    'result' => true
                ];
                $res = $this->auditOpenApply($applyUserId, '系统', $audit);
                if (!$res) {
                    throw new ValidateException($this->error);
                }
            }

            if ($applyUserType == 'organization') {
                $organizationQuotaRw = new OrganizationQuotaRw();
                $trade = [
                    "describe" => "开户申请【{$organization['name']}】",
                    'organizationId' => $applyOrganizationId,
                    'value' => 1,
                    'businessType' => QuotaBusinessTypeEnum::E2,
                    'businessId' => $openApply['id']
                ];
                $organizationQuotaRw->updateAccount($trade);
            }
            Db::commit();
        } catch (Exception|PDOException|ValidateException $e) {
            Db::rollback();
            $this->setError($e->getMessage());
            return false;
        }
        return true;
    }

    public function auditOpenApply(string $auditUserId, string $auditUserName, array $data)
    {
        Db::startTrans();
        try {
            $openApplyId = $data['openApplyId'];
            $organizationOpenApply = new OrganizationOpenApply();
            $openApply = $organizationOpenApply->where(['id' => $openApplyId])->find();
            if (!$openApply) {
                throw new ValidateException('申请记录不存在');
            }
            if ($openApply['applyState'] != AuditStateEnum::E1) {
                throw new ValidateException('该申请已被审核');
            }
            $result = $data['result'];
            $cnt = $organizationOpenApply->updateAuditById($openApplyId, $auditUserId, $auditUserName, $result);
            if (!$cnt) {
                throw new ValidateException('更新审核状态失败，请稍后重试');
            }
            $applyUserType = $openApply['applyUserType'];
            if ($result) {
                $organization = Organization::where(['id' => $openApply['organizationId']])->find();
                $organization->status = OrganizationStateEnum::E2;
                $organization->save();
                (new OrganizationUser)->createAdmin($organization);
                (new OrganizationData)->createData($organization);
                $organizationRewardService = new OrganizationRewardService();
                //申请时明星校区经销商添加奖励课时
                $organizationRewardService->campusFirstBuyReward($organization['level'], $organization['id']);
                //超级校区奖励邀请人
                $organizationRewardService->invitationReward($organization['parentId'], $organization['inviteId']);
            } else {
                $applyOrganizationId = $openApply['applyOrganizationId'];
                if ($applyUserType == 'organization') {
                    $trade = [
                        'describe' => "开户申请审核失败【{$openApply['organizationName']}】",
                        'organizationId' => $applyOrganizationId,
                        'value' => 1,
                        'businessType' => QuotaBusinessTypeEnum::E3,
                        'businessId' => $openApply['id']
                    ];
                    $organizationQuotaRw = new OrganizationQuotaRw();
                    $organizationQuotaRw->updateAccount($trade);
                }
            }
            Db::commit();
        } catch (Exception|PDOException|ValidateException $e) {
            Db::rollback();
            $this->setError($e->getMessage());
            return false;
        }
        return true;
    }
}
